package org.budo.support.javax.servlet.filter.request.read.repeatable;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;

import javax.servlet.ServletInputStream;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

import org.apache.commons.io.IOUtils;
import org.budo.support.lang.util.ListUtil;

/**
 * @author lmw
 */
public class RepeatableReadRequestWrapper extends HttpServletRequestWrapper {
    private List<String> headerNames;

    private byte[] inputStreamBytes;

    public RepeatableReadRequestWrapper(ServletRequest request) {
        super((HttpServletRequest) request);
    }

    public Enumeration<String> getHeaderNames() {
        if (null != this.headerNames) {
            return Collections.enumeration(this.headerNames);
        }

        this.headerNames = ListUtil.enumerationToList(super.getHeaderNames());
        return Collections.enumeration(this.headerNames);
    }

    public ServletInputStream getInputStream() throws IOException {
        if (null != this.inputStreamBytes) {
            return new ByteArrayServletInputStream(this.inputStreamBytes);
        }

        ServletInputStream inputStream = super.getInputStream();
        this.inputStreamBytes = IOUtils.toByteArray(inputStream);
        return new ByteArrayServletInputStream(this.inputStreamBytes);
    }

    @Override
    public BufferedReader getReader() throws IOException {
        InputStreamReader inputStreamReader = new InputStreamReader(this.getInputStream(), this.getCharacterEncoding());
        return new BufferedReader(inputStreamReader);
    }

    public String toString() {
        return super.toString() + ", wrapped(" + this.getRequest() + ")";
    }
}